#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "BlockQueue.hpp"
#include "Thread.hpp"
using namespace std;

#define PLATESIZE 10
#define PRODUCERSIZE 5
#define CONSUMERSIZE 4

void producer(BlockingQueue<int>& bq)
{
    string name = ThreadModule::Thread::GetMyName();
    for(int i = 0; i < 10; i++)
    {
        int weight = rand() % 9 + 1;
        bq.push(weight);
        printf("[生产者%s]向盘中放入一个重%dkg的苹果\n", name.c_str(), weight);
    }
}

void consumer(BlockingQueue<int>& bq)
{
    string name = ThreadModule::Thread::GetMyName();
    while(true)
    {
        int weight = bq.pop();
        printf("[消费者%s]从盘中取出一个重%dkg的苹果\n", name.c_str(), weight);
    }
}

int main()
{
    srand((unsigned int)time(nullptr));
    BlockingQueue<int> bq(10);

    // 创建生产者
    vector<ThreadModule::Thread> producers;
    for(int i = 0; i < PRODUCERSIZE; i++)
    {
        string name = "producer-" + to_string(i);
        producers.emplace_back(name, producer, bq);
    }
    // 创建消费者
    vector<ThreadModule::Thread> consumers;
    for(int i = 0; i < CONSUMERSIZE; i++)
    {
        string name = "consumer-" + to_string(i);
        consumers.emplace_back(name, consumer, bq);
    }

    // 启动生产者
    for(auto& thread : producers)
        thread.Start();
    // 启动消费者
    for(auto& thread : consumers)
        thread.Start();

    // 等待生产者生产结束
    for(auto& thread : producers)
        thread.Join();
    // 等待苹果被消费完
    while(!bq.empty())
    {
        usleep(100);
    }
    // 清理消费者
    for(auto& thread : consumers)
        thread.Stop();

    return 0;
}